#ifdef __GNUG__
#pragma implementation
#endif

#include "Iterator.h"
#include "Container.h"

#include "Error.h"

//---- IteratorBase ------------------------------------------------------------

IteratorBase::~IteratorBase()
{
}

void IteratorBase::Reset()
{
	AbstractMethod("IteratorBase::Reset");
}

Object *IteratorBase::operator()()
{
	AbstractMethod("IteratorBase::operator()");
	return 0;
}

//---- Iterator ----------------------------------------------------------------

Iterator::Iterator()
{
	activated= terminated= FALSE;
	next= prev= 0;
}

Iterator::~Iterator()
{
	if (IsActive())
		Error("Iterator::~Iterator", "is active");
}

void Iterator::Reset()
{
	Terminate();
	activated= terminated= FALSE;
}

//---- support for robust iterators

bool Iterator::Activate()
{
	Container *ct;

	if (! activated) {
		activated= TRUE;
		if (ct= GetContainer())
			ct->IteratorActivates(this);
		else {
			terminated= TRUE;
			Warning("Iterator::Activate", "GetContainer is 0");
		}
	}
	return ! terminated;
}

void Iterator::Terminate()
{
	Container *ct;

	if (IsActive()) {
		if (ct= GetContainer())
			ct->IteratorTerminates(this);
	}
	activated= terminated= TRUE;
}

Container *Iterator::GetContainer()
{
	AbstractMethod("Iterator::GetContainer");
	return 0;
}

void Iterator::Detach()
{
	activated= terminated= TRUE;
}

void Iterator::ChainIn(Iterator *anchor)
{
	if (prev == 0 && next == 0) {
		prev= anchor->prev;
		next= anchor;
		anchor->prev->next= this;
		anchor->prev= this;
	} else
		Error("Iterator::ChainIn", "prev or next != 0");
}

void Iterator::ChainOut()
{
	if (next && prev) {   // && prev->next == this && next->prev == this
		next->prev= prev;
		prev->next= next;
		prev= 0;
		next= 0;
	} else
		Error("Iterator::ChainOut", "next or prev inconsistent");
}

//---- Iterator0 ---------------------------------------------------------------

Iterator0::Iterator0()
{
}

Object *Iterator0::operator()()
{
	return 0;
}

void Iterator0::Reset()
{
}

//---- Iterator1 ---------------------------------------------------------------

Iterator1::Iterator1(Object *o)
{
	op= o;
	n= 0;
}

Object *Iterator1::operator()()
{
	if (n == 0) {
		n= 1;
		return op;
	}
	n= 0;
	return 0;
}

void Iterator1::Reset()
{
	n= 0;
}

